package com.thomsonreuter.search.compare;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jayway.jsonpath.JsonPath;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import javax.net.ssl.HttpsURLConnection;
import java.io.*;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;


public class GenerateAppsReqest {
    private static final Object BASE_URL = "http://localhost:5000";
    private static long requestsCount = 0;
    private static OkHttpClient client =
            new OkHttpClient.Builder()
                    .connectTimeout(0, TimeUnit.SECONDS)//设置连接超时时间
                    .readTimeout(0, TimeUnit.SECONDS)//设置读取超时时间
                    .build();

    private static long min, max;
    private static long total,count;
    private static Map<String,StatusTime> status2count = new HashMap();
    static class StatusTime {
        public long total;
        public long count;

        public long max;
        public long min;

        public StatusTime(long total, long count) {
            this.total = total;
            this.count = count;
        }
    }

    public static void main(String[] args) throws IOException {
        //File file = new File("appsperftest.csv");
        //Files.newBufferedWriter(file.toPath(), StandardCharsets.UTF_8);

//        OutputStreamWriter outputWriter = new OutputStreamWriter(
//                new FileOutputStream("aaauuid.csv"),
//                Charset.forName("UTF-8").newEncoder()
//        );
//
//
//        GenerateRequestsUsingAAAESUUID(outputWriter);
//
//        outputWriter.close();



//        OutputStreamWriter outputWriter = new OutputStreamWriter(
//                new FileOutputStream("ASWSRAPRequests.csv"),
//                Charset.forName("UTF-8").newEncoder()
//        );
//
//        GenerateRAPRequestsUsingUUIDFile(outputWriter);
//
//        outputWriter.close();

        //ExcuteGetVersionListUsingUUIDFile();


        OutputStreamWriter outputWriter = new OutputStreamWriter(
                new FileOutputStream("ASWSLookUpRequests.csv"),
                Charset.forName("UTF-8").newEncoder()
        );

        GenerateLookupRequestsUsingLogFile("lookup.2020-12-14.log",outputWriter);
        GenerateLookupRequestsUsingLogFile("lookup.2020-12-14.2.log",outputWriter);
        GenerateLookupRequestsUsingLogFile("lookup.2020-12-14.3.log",outputWriter);

        while ( requestsCount < 2000000){
            GenerateLookupRequestsUsingLogFile("lookup.2020-12-14.log",outputWriter);
            GenerateLookupRequestsUsingLogFile("lookup.2020-12-14.2.log",outputWriter);
            GenerateLookupRequestsUsingLogFile("lookup.2020-12-14.3.log",outputWriter);
        }
        outputWriter.close();
    }

    private static void generateRequestsUsingASWSUUID(
                                        OutputStreamWriter outputWriter) throws IOException {
        String params = "apikey=67495bb7-22d7-4e31-b84a-702b96396370&$top=10&$skip=0&$select=BusinessEntity,DocumentTitle,PermID";
        String url = "/search/Apps";
        String method = "GET";

        String api = "/v3/People";
        String apiUrl = String.format("%s%s", BASE_URL, api);

        //请求参数
        long skip = 0;
        Map postMap = new HashMap();
        postMap.put("select", "PI");
        postMap.put("top", "100");

        while (skip < 10000) {
            System.out.println("skip:" + skip );
            postMap.put("skip", skip);
            //ObjectMapper objectMapper = new ObjectMapper();
            //String content = objectMapper.writeValueAsString(postMap);
            FormBody body = new FormBody.Builder()
                    .add("select","PI").add("top", "100")
                    .add("skip",String.valueOf(skip))
                    .add("filter","LocationAccountID ne null")
                    .build();

            Request request = new Request.Builder()
                    .url(apiUrl)
                    .post(body) //post请求
                    .build();
            final Call call = client.newCall(request);
            Response rs = call.execute();

            List<String> PIs = JsonPath.read(rs.body().string(), "$.d[*].PI");
            for (String PI:PIs) {
                System.out.println(PI);
                String aswrequest = buildRequest(method, url, params, PI);

                outputWriter.write(aswrequest);
            }

//            call.enqueue(new Callback() {
//                @Override
//                public void onFailure(Call call, IOException e) {
//                    System.out.println("failed");
//                }
//
//                @Override
//                public void onResponse(Call call, Response response) throws IOException {
//
//                    generateRequests(response, method, url, params, outputWriter);
//                }
//            });

            skip += 100;
        }
    }

    private static int  testURL(String baseUrl,String url ) {
        String apiUrl = String.format("%s%s", baseUrl, url);

        Request request = new  Request.Builder().url(apiUrl).build();

        int i = 1;
        try {
            Response response = client.newCall(request).execute();
            // 4 判断是否请求成功
            if(response.isSuccessful()){
                // 得到响应体中的身体,将其转成  string
                String string = response.body().string();
                System.out.println(string);
            }
            else{
                i = 0;
            }
            response.close();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            i = 0;
        }

        return i;
    }

    private static void GenerateRequestsUsingUUIDFile(OutputStreamWriter outputWriter) throws IOException {

        String params = "apikey=67495bb7-22d7-4e31-b84a-702b96396370&$top=10&$skip=0&$select=BusinessEntity,DocumentTitle,PermID";
        String url = "/search/Apps";
        String method = "GET";

        InputStream inputStream = new FileInputStream("uuidlistfromprod.txt");

        InputStreamReader inputStreamReader =
                new InputStreamReader(inputStream, Charset.forName("UTF-8"));

        BufferedReader bufReader=new BufferedReader(inputStreamReader);
        String contentLine = null;
        while ((contentLine=bufReader.readLine())!= null) {
            String arr[] = contentLine.trim().split(" ");
            System.out.println(arr[1]);
            String request =  buildRequest( method, url, params, arr[1]);
            outputWriter.write(request);
        }
    }


    private static void GenerateRAPRequestsUsingUUIDFile(OutputStreamWriter outputWriter) throws IOException {

        String params = "{ 'Tags': ['Search'] }";

        String url = "/getversionslist";
        String method = "POST";

        InputStream inputStream = new FileInputStream("uuidlistfromprod.txt");

        InputStreamReader inputStreamReader =
                new InputStreamReader(inputStream, Charset.forName("UTF-8"));

        BufferedReader bufReader=new BufferedReader(inputStreamReader);
        String contentLine = null;
        while ((contentLine=bufReader.readLine())!= null) {
            String arr[] = contentLine.trim().split(" ");
            System.out.println(arr[1]);
            String request =  buildRapRequest( method, url, params, arr[1]);
            outputWriter.write(request);
        }
    }

    private static void GenerateLookupRequestsUsingLogFile( String logfile,OutputStreamWriter outputWriter) throws IOException {
        FileInputStream fis = new FileInputStream(logfile);
        InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String line = null;

        while ((line = br.readLine()) != null) {
            int pos       = line.indexOf("\"");
            line          = line.substring(pos+1);
            pos           = line.indexOf("\"");
            line          = line.substring(0,pos);
            String[] arr  = line.split(" ");
            String method = arr[0];

            String betaUrl = replaceuuid(arr[1],"PAXTRA27775");
            //int i = testURL("http://hdcs-analytics-search.int.thomsonreuters.com",betaUrl);
            //int j = testURL("http://hdcp-analytics-search.int.thomsonreuters.com",betaUrl);

            //if (i == 0 ) continue;

            pos = betaUrl.indexOf("?");
            if( pos > 0) {
                String url   = betaUrl.substring(0, pos);
                String param = betaUrl.substring(pos + 1);

                String csvLine = buildLookUpRequest(method, url, param);
                outputWriter.write(csvLine);
            }else{
                String url = betaUrl ;
                String param =  "\" \"" ;

                String csvLine = buildLookUpRequest(method, url, param);
                outputWriter.write(csvLine);
            }

            requestsCount++;

        }
        fis.close();
    }

    private static String replaceuuid(String s, String paxtra27775) {
        int pos = s.indexOf("uuid=");
        if( pos < 0) return s;
        String uuidUrl   = s.substring(0,pos);
        String remaining = s.substring(pos);
        String newUrl    = uuidUrl;
        int endpos       = remaining.indexOf("&");
        if( endpos > 0){
            remaining = remaining.substring(endpos);
            newUrl = uuidUrl + "uuid=" + paxtra27775 + remaining;
        }else{
            newUrl = uuidUrl + "uuid=" + paxtra27775;
        }
        return newUrl;
    }

    private static void ExcuteGetVersionListUsingUUIDFile() throws IOException {

        String params = "{ 'Tags': ['Search'] }";

        String url = "/getversionslist";
        String method = "POST";

        InputStream inputStream = new FileInputStream("uuidlistfromprod.txt");

        InputStreamReader inputStreamReader =
                new InputStreamReader(inputStream, Charset.forName("UTF-8"));

        BufferedReader bufReader=new BufferedReader(inputStreamReader);
        String contentLine = null;
        while ((contentLine=bufReader.readLine())!= null) {
            String arr[] = contentLine.trim().split(" ");
            System.out.println(arr[1]);
            loadEntitledAppIds(arr[1]);
        }
        inputStreamReader.close();

        System.out.println("max : " + max + " min: " + min + " avg: " + total/count);
        status2count.forEach((k,v)->{
            System.out.println("status : " + k  +  " count: " + v.count  + "avg: " + v.total / v.count + " max:" + v.max + " min: " + v.min);
        });
    }

    private static void loadEntitledAppIds(String uuid) throws IOException {
        String rapBaseUrl = "https://a205149-api-el-eu-west-1-ppe-beta.desktop-preprod.aws-int.thomsonreuters.com";
        String proxyHost = "webproxy.pln.corp.services";
        String proxyPort = "80";
        String body = "{ \"Tags\": [\"Search\"] }";
         loadHelperHttps(rapBaseUrl, proxyHost,proxyPort,"/getversionslist", uuid,body);
    }

    private static void loadHelperHttps(String baseUrl,
                                         String proxyHost,
                                         String proxyPort,
                                         String cmd,
                                         String uuid,
                                         String body
                                          ) throws IOException {

        long startTime=System.currentTimeMillis();   //获取开始时间
        HttpsURLConnection conn = makeHttpsConnection(baseUrl + cmd,proxyHost,proxyPort);

        // Note: DACS doesn't seem to understand charsets or GZIP response encoding, so don't bother asking
        // (based on browser experimentation - it doesn't return charset, and doesn't return gzip even if asked)
        //
        // Not sure yet whether we should be sending "Connection":"keep-alive". If we can get away with one service,
        // possibly not; we don't want to tie up a pooled connection (on either side) if we're not immediately about to
        // make another request.
        conn.setRequestProperty("UUID", uuid);
        conn.setRequestProperty("Content-Type",  "application/json");

        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestMethod("POST");

        conn.connect();

//        String body = "{ \"Tags\": [\"Search\"] }";
         BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream(), "UTF-8"));
         writer.write(body);
         writer.close();

        int status = conn.getResponseCode();
        Map<String,Object> retMap = new HashMap<>();
        retMap.put("responseCode",status);
        long endTime=System.currentTimeMillis(); //获取结束时间

        long duration = (endTime-startTime);
        total += duration;
        count +=  1;
        if (min < duration)
        {
            min = duration;
        }

        if( duration > max){
            max = duration;
        }

        System.out.println("程序运行时间： "+ duration +"ms" + "status:" + status);
        StatusTime statusTime = status2count.get(String.valueOf(status));

        if (statusTime  == null){
            statusTime = new StatusTime(duration,1);

            statusTime.min = duration;
            statusTime.max = duration;

            status2count.put(String.valueOf(status), statusTime);
        }
        else{
            statusTime.count ++;
            statusTime.total += duration;

            if (statusTime.min < duration)
            {
                statusTime.min = duration;
            }

            if( duration > statusTime.max){
                statusTime.max = duration;
            }

            status2count.put(String.valueOf(status), statusTime);
        }
        if( status == 400){ // 400 means the request uuid is not int AAA system
            try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getErrorStream()))) {
                StringBuilder sb = new StringBuilder();
                br.lines().forEach(s->{
                    sb.append(s);
                });
                String result = sb.toString();
                retMap.put("responseBody",result);
                return ;
            }
        }


        try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
            StringBuilder sb = new StringBuilder();
            br.lines().forEach(s->{
                sb.append(s);
            });
            String result = sb.toString();
            retMap.put("responseBody",result);
            return;
        }
    }
    static HttpsURLConnection makeHttpsConnection(String url, String proxyHost, String proxyPort) throws IOException {
        if(!StringUtils.isEmpty(proxyHost) && !StringUtils.isEmpty(proxyPort)){
            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost,
                    Integer.parseInt(proxyPort)));
            return (HttpsURLConnection) new URL(url).openConnection(proxy);
        }else{
            return (HttpsURLConnection) new URL(url).openConnection();
        }
    }

    private static void GenerateRequestsUsingAAAESUUID(OutputStreamWriter outputWriter)
    {
        String params = "apikey=67495bb7-22d7-4e31-b84a-702b96396370&$top=10&$skip=0&$select=BusinessEntity,DocumentTitle,PermID";
        String url = "/search/Apps";
        String method = "GET";

        String index = "cat_aaa_person_0.0.22";
        String endpoint = "http://hdcs-analytics-search-elastic.int.thomsonreuters.com:9200/";

        try {
            InputStream is = GenerateAppsReqest.class.getClassLoader().getResourceAsStream("uuid.json");
            InputStreamReader inputStreamReader =
                    new InputStreamReader(is, Charset.forName("UTF-8"));
            BufferedReader bufReader=new BufferedReader(inputStreamReader);
            StringBuilder queryStrBuilder = new StringBuilder();

            bufReader.lines().forEach(line ->{
                queryStrBuilder.append(line);
            });
            bufReader.close();
            ObjectMapper objectMapper = new ObjectMapper();
            String scrollIdJson = getFirstPageWithScroll(endpoint + "/"+ index,queryStrBuilder.toString());
            System.out.println(scrollIdJson);
            Map scrollIdMap = objectMapper.readValue(scrollIdJson, Map.class);
            String scrollId = (String)scrollIdMap.get("_scroll_id");
            Map scrollMap = new HashMap();
            scrollMap.put("scroll","2m");
            scrollMap.put("scroll_id",scrollId);

            String scrollQuery = objectMapper.writeValueAsString(scrollMap);
            while (true) {

                String page = getNextPageWithScrollId(endpoint, scrollQuery);
                //System.out.println(page);
                if (page == null ) break;
                List<String> PIs = JsonPath.read(page, "$..PI");
                if( PIs.size() == 0){
                    break;
                }
                for (String PI : PIs) {
                    System.out.println(PI);
                    String aswrequest = buildRequest(method, url, params, PI);

                    outputWriter.write(aswrequest);
                }
            }
        }catch(IOException ioe){
            ioe.printStackTrace();
        }
    }

    private static String buildRapRequest(String method, String url, String params, String PI) {
        StringBuilder builder = new StringBuilder();
        builder.append(method);
        builder.append(",");
        builder.append(url);
        builder.append(",");
        builder.append("\"");
        builder.append(params);
        builder.append("\"");
        builder.append(",");
        builder.append(PI);
        builder.append("\n");
        return builder.toString();
    }

    private static String buildRequest(String method, String url, String params, String PI) {
        StringBuilder builder = new StringBuilder();
        builder.append(method);
        builder.append(",");
        builder.append(url);
        builder.append(",");
        builder.append("\"");
        builder.append("uuid=");
        builder.append(PI);
        builder.append("&");
        builder.append(params);
        builder.append("\"");
        builder.append("\n");
        return builder.toString();
    }

    private static String buildLookUpRequest(String method, String url, String params) {
        StringBuilder builder = new StringBuilder();
        builder.append(method);
        builder.append(",");
        builder.append(url);
        builder.append(",");
        builder.append("\"");
        builder.append(params);
        builder.append("\"");
        builder.append("\n");
        return builder.toString();
    }

    public static String getFirstPageWithScroll(final String index ,String queryStr) throws IOException {

        StringBuilder scrollindex = new StringBuilder();
        scrollindex.append(index);
        scrollindex.append("/_search");
        scrollindex.append("?scroll=");
        scrollindex.append("5m");
        scrollindex.append("&search_type=scan");

        final Request request = new Request.Builder().url(scrollindex.toString()).post(RequestBody.create(MediaType.get("text/plain"), queryStr)).build();
        try (Response response = client.newCall(request).execute()) {

            return response.code() == 200 ? response.body().string() : null;
        }
    }

    public static String getNextPageWithScrollId(final String index, String queryStr) throws IOException {

        StringBuilder scrollindex = new StringBuilder();
        scrollindex.append(index);
        scrollindex.append("_search");
        scrollindex.append("/scroll");

        //scrollindex.append("&search_type=scan");

        final Request request = new Request.Builder().url(scrollindex.toString()).post(RequestBody.create(MediaType.get("text/plain"), queryStr)).build();
        try (Response response = client.newCall(request).execute()) {

            return response.code() == 200 ? response.body().string() : null;
        }
    }

}
